#include <QtGui>
#include "GraphicsEngine.h"
#include "GameEngine.h"
#include "Player.h"

GraphicsEngine::GraphicsEngine()
{
	centralWindow = new QWidget(this);
	scene = new GlWindow(this);
	infos = new InfoWindow(this);

	QHBoxLayout *layout = new QHBoxLayout;
	layout->addWidget(scene);
	layout->addWidget(infos);
	centralWindow->setLayout(layout);
    setCentralWidget(centralWindow);

    createActions();
    createMenus();
    createToolBars();
	createStatusBar();
	
	
	setUnifiedTitleAndToolBarOnMac ( true );

	setWindowTitle(VersionSoft);
    setWindowIcon(QIcon(":/images/QtM.png"));
}


GraphicsEngine::~GraphicsEngine()
{
	delete centralWindow;
	delete scene;
	delete infos;
}


void GraphicsEngine::initialization( GameEngine *ge )
{
	connecting( ge );
	readSettings();
	ge->initializationDisplay();
}


void GraphicsEngine::connecting( GameEngine *ge )
{
	if( ge != NULL )
	{
		//Connection SIGNALS-SLOTS du GameEngine et GraphicsEngine
		connect( this, SIGNAL( startNewGame() ), ge, SLOT( initialization() ) );
		connect( ge, SIGNAL( playerWins(Player*) ), this, SLOT( displayWinner(Player*) ) );
		connect( ge, SIGNAL( enableUndoMoveAction(bool) ), this, SLOT( setDisplayUndoMoveAction(bool) ) );
		connect( ge, SIGNAL( enableRedoMoveAction(bool) ), this, SLOT( setDisplayRedoMoveAction(bool) ) );
		connect( this, SIGNAL( undoMoveAsked() ), ge, SLOT( undoMoveGlobal() ) );
		connect( this, SIGNAL( redoMoveAsked() ), ge, SLOT( redoMoveGlobal() ) );
		
		
		//Connection des modules GlWindow et InfosWindow
		scene->connecting( ge );
		infos->connecting( ge );

		//Initialisation de l'affichage des infos de jeux
	}
}


void GraphicsEngine::closeEvent(QCloseEvent *event)
{
	int r = QMessageBox::warning(this,VersionSoft,tr("Do you want really to quit this application ?"),
				QMessageBox::Yes, QMessageBox::No | QMessageBox::Default);
	if(r == QMessageBox::Yes){
		writeSettings();
		event->accept();
	}
	else{
		event->ignore();
	}
}

void GraphicsEngine::createActions()
{
    newAction = new QAction(tr("&New"), this);
    newAction->setIcon(QIcon(":/images/NewGame.png"));
    newAction->setShortcut(tr("Ctrl+N"));
    newAction->setStatusTip(tr("Play a new game"));
    connect(newAction, SIGNAL(triggered()), this, SLOT(newGame()));

    saveAction = new QAction(tr("&Save"), this);
    saveAction->setIcon(QIcon(":/images/SaveGame.png"));
    saveAction->setShortcut(tr("Ctrl+S"));
    saveAction->setStatusTip(tr("Save this game"));
    connect(saveAction, SIGNAL(triggered()), this, SLOT(saveGame()));

    loadAction = new QAction(tr("&Load"), this);
    loadAction->setIcon(QIcon(":/images/LoadGame.png"));
    loadAction->setShortcut(tr("Ctrl+L"));
    loadAction->setStatusTip(tr("Load a saved game"));
    connect(loadAction, SIGNAL(triggered()), this, SLOT(loadGame()));
    
    exitAction = new QAction(tr("E&xit"), this);
    exitAction->setShortcut(tr("Ctrl+X"));
    exitAction->setStatusTip(tr("Exit the application"));
    connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

    regularMovesAction = new QAction(tr("Regular Moves"), this);
    regularMovesAction->setCheckable(true);
	regularMovesAction->setChecked(true);
	regularMovesAction->setStatusTip(tr("Show or hide regular moves"));
	connect(regularMovesAction, SIGNAL(triggered()), this, SLOT(updateSettingRegularMoves()));

    lastMoveAction = new QAction(tr("Last Move"), this);
    lastMoveAction->setCheckable(true);
	lastMoveAction->setChecked(true);
	lastMoveAction->setStatusTip(tr("Show or hide last move"));
	connect(lastMoveAction, SIGNAL(triggered()), this, SLOT(updateSettingLastMove()));

    animationAction = new QAction(tr("Animations"), this);
    animationAction->setCheckable(true);
	animationAction->setChecked(true);
	animationAction->setStatusTip(tr("Show or hide animations"));
	connect(animationAction, SIGNAL(triggered()), this, SLOT(updateSettingAnimation()));
	
	

    undoMoveAction = new QAction(tr("&Undo Move"), this);
    undoMoveAction->setIcon(QIcon(":/images/UndoMove.png"));
    undoMoveAction->setShortcut(tr("Ctrl+U"));
    undoMoveAction->setStatusTip(tr("Undo the last move"));
    connect(undoMoveAction, SIGNAL(triggered()), this, SLOT(undoMove()));
	undoMoveAction->setEnabled(false);

    redoMoveAction = new QAction(tr("&Redo Move"), this);
    redoMoveAction->setIcon(QIcon(":/images/RedoMove.png"));
    redoMoveAction->setShortcut(tr("Ctrl+R"));
    redoMoveAction->setStatusTip(tr("Redo the last move canceled"));
    connect(redoMoveAction, SIGNAL(triggered()), this, SLOT(redoMove()));
	redoMoveAction->setEnabled(false);
	
    preferencesAction = new QAction(tr("&Preferences"), this);
    preferencesAction->setIcon(QIcon(":/images/Preferences.png"));
	preferencesAction->setShortcut(tr("Ctrl+P"));
    preferencesAction->setStatusTip(tr("Configure the options game"));
    connect(preferencesAction, SIGNAL(triggered()), this, SLOT(preferences()));

/*    breakAction = new QAction(tr("Break"), this);
    breakAction->setCheckable(true);
	breakAction->setChecked(true);
	breakAction->setStatusTip(tr("Take a break"));
//	connect....

    optionsAction = new QAction(tr("&Options"), this);
    optionsAction->setStatusTip(tr("Show Options"));

    aboutAction = new QAction(tr("About..."), this);
    aboutAction->setStatusTip(tr("About..."));

    helpAction = new QAction(tr("&Help"), this);
    helpAction->setStatusTip(tr("Help on line"));
*/
}

void GraphicsEngine::createMenus()
{
//---------- Création  Menu "File" -------------
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAction);
    fileMenu->addAction(saveAction);
    fileMenu->addAction(loadAction);
    fileMenu->addSeparator();
	fileMenu->addAction(exitAction);

//---------- Création  Menu "View" -------------
	viewMenu = menuBar()->addMenu(tr("&View"));
	viewMenu->addAction(regularMovesAction);
	viewMenu->addAction(lastMoveAction);
	viewMenu->addAction(animationAction);
	
//---------- Création  Menu "Tools" -------------
	toolsMenu = menuBar()->addMenu(tr("&Tools"));
	toolsMenu->addAction(undoMoveAction);
	toolsMenu->addAction(redoMoveAction);
    toolsMenu->addSeparator();
    toolsMenu->addAction(preferencesAction);
/*	toolsMenu->addSeparator();
	toolsMenu->addAction(breakAction);
	toolsMenu->addSeparator();
	toolsMenu->addAction(optionsAction);
*/
//---------- Création  Menu "Help" -------------
/*	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAction);
	helpMenu->addAction(helpAction);
*/}

void GraphicsEngine::createToolBars()
{
	fileToolBar = addToolBar(tr("&File"));
	fileToolBar->addAction(newAction);
	fileToolBar->addAction(saveAction);
	fileToolBar->addAction(loadAction);
	
	toolsToolBar = addToolBar(tr("&Tools"));
	toolsToolBar->addAction(undoMoveAction);
	toolsToolBar->addAction(redoMoveAction);
	toolsToolBar->addAction(preferencesAction);
}

void GraphicsEngine::createStatusBar()
{
	statusBarLabel = new QLabel("");
//	statusBarLabel->setAlignment(Qt::AlignHCenter);
	statusBar()->addWidget(statusBarLabel,1);
}


void GraphicsEngine::writeSettings()
{
//	QSettings settings("Maurryson Inc.", "QthelloMania");
	infos->writeSettings();
//	scene->writeSettings();
}

void GraphicsEngine::readSettings()
{
//	QSettings settings("Maurryson Inc.", "QthelloMania");
	infos->readSettings();
//	scene->readSettings(settings);
}


void GraphicsEngine::newGame()
{
    QMessageBox::information(this, VersionSoft, tr("New Game !"),
            QMessageBox::Ok | QMessageBox::Default);
	emit startNewGame();
}

bool GraphicsEngine::saveGame()
{
    QMessageBox::information(this, VersionSoft, tr("Save Game !\n(Not yet implemented...)"),
            QMessageBox::Ok | QMessageBox::Default);
    return true;
}

bool GraphicsEngine::loadGame()
{
	QMessageBox::information(this, VersionSoft, tr("Load Game !\n(Not yet implemented...)"),
				QMessageBox::Ok | QMessageBox::Default);
	return true;
}

void GraphicsEngine::preferences()
{
//Récupération des valeurs des joueurs
	QString name_p1 = infos->getPlayer(p1)->getName(),
			name_p2 = infos->getPlayer(p2)->getName();
	int type_p1, type_p2;
	switch( infos->getPlayer(p1)->getType() )
	{
		case AI_1:
			type_p1 = 1;
			break;
		case AI_2:
			type_p1 = 2;
			break;
		case AI_3:
			type_p1 = 3;
			break;
		case Local:
		default:
			type_p1 = 0;
			break;
	}
	switch( infos->getPlayer(p2)->getType() )
	{
		case AI_1:
			type_p2 = 1;
			break;
		case AI_2:
			type_p2 = 2;
			break;
		case AI_3:
			type_p2 = 3;
			break;
		case Local:
		default:
			type_p2 = 0;
			break;
	}

//Création de la boite de dialogue
	PreferencesDialog dialog(this);

//MAJ des valeurs de la boite de dialogue liées aux joueurs
//	cout << "## Avt MAJ Préférences ##"<< endl;
//	cout << "	name_p1: " << string(name_p1) << "	name_p2: " << string(name_p2) << endl;
//	cout << "	type_p1: " << type_p1 << "	type_p2: " << type_p2 << endl;
	dialog.setNames( name_p1, name_p2 );
	dialog.setTypes(type_p1,type_p2);
	
	
	if( dialog.exec() )
	{
		bool modif_type = false;
		
		if( name_p1 != dialog.lineEdit_name_p1->text() )  //Si le nom du player 1 a changé
		{
			infos->getPlayer(p1)->setName( dialog.lineEdit_name_p1->text() );  //MAJ donnees
			infos->setNameP1( dialog.lineEdit_name_p1->text() );  //MAJ affichage
		}
		if( name_p2 != dialog.lineEdit_name_p2->text() )  //Si le nom du player 2 a changé
		{
			infos->getPlayer(p2)->setName( dialog.lineEdit_name_p2->text() );  //MAJ donnees
			infos->setNameP2( dialog.lineEdit_name_p2->text() );  //MAJ affichage
		}
		if( type_p1 != dialog.comboBox_type_p1->currentIndex() )  //Si le type du player 1 a changé
		{
			switch( dialog.comboBox_type_p1->currentIndex() )
			{
				case 1:
					infos->getPlayer(p1)->setType( AI_1 );
					infos->setTypeP1( AI_1 );
					break;
				case 2:
					infos->getPlayer(p1)->setType( AI_2 );
					infos->setTypeP1( AI_2 );
					break;
				case 3:
					infos->getPlayer(p1)->setType( AI_3 );
					infos->setTypeP1( AI_3 );
					break;
				case 0:
				default:
					infos->getPlayer(p1)->setType( Local );
					infos->setTypeP1( Local );
					break;
			}
			modif_type = true;
		}
		if( type_p2 != dialog.comboBox_type_p2->currentIndex() )  //Si le type du player 2 a changé
		{
			switch( dialog.comboBox_type_p2->currentIndex() )
			{
				case 1:
					infos->getPlayer(p2)->setType( AI_1 );
					infos->setTypeP2( AI_1 );
					break;
				case 2:
					infos->getPlayer(p2)->setType( AI_2 );
					infos->setTypeP2( AI_2 );
					break;
				case 3:
					infos->getPlayer(p2)->setType( AI_3 );
					infos->setTypeP2( AI_3 );
					break;
				case 0:
				default:
					infos->getPlayer(p2)->setType( Local );
					infos->setTypeP2( Local );
					break;
			}
			modif_type = true;
		}
		if( modif_type )  //Si le type d'un des joueurs a chnagé -> nouvelle partie !
		{
			emit startNewGame();
		}
	}
}


void GraphicsEngine::displayWinner(Player *p)
{
	if( p != NULL ) //Si il y a un vainqueur
	{
		QString str = p->getName() + " wins the game !";
	    QMessageBox::information(this,VersionSoft,str,
	            QMessageBox::Ok | QMessageBox::Default);
	}
	else //Pas de vainqueur -> Deuce!
	{
	    QMessageBox::information(this,VersionSoft,tr("Deuce !"),
	            QMessageBox::Ok | QMessageBox::Default);
	}
	
	emit startNewGame();
}

void GraphicsEngine::updateSettingRegularMoves()
{
	scene->setRegularMovesSetting( regularMovesAction->isChecked() );
}

void GraphicsEngine::updateSettingLastMove()
{
	scene->setLastMoveSetting( lastMoveAction->isChecked() );
}

void GraphicsEngine::updateSettingAnimation()
{
	scene->setAnimationSetting( animationAction->isChecked() );
}


void GraphicsEngine::setDisplayUndoMoveAction(bool b)
{
	undoMoveAction->setEnabled(b);
}

void GraphicsEngine::setDisplayRedoMoveAction(bool b)
{
	redoMoveAction->setEnabled(b);
}

void GraphicsEngine::undoMove()
{
	//annulation de la demande de coup du moteur de jeu
	scene->setMoveAsked(false);
	emit undoMoveAsked();
}

void GraphicsEngine::redoMove()
{
	//annulation de la demande de coup du moteur de jeu
	scene->setMoveAsked(false);
	emit redoMoveAsked();
}
